<script setup lang="ts">
import type { Props, Emits } from './utils/types'
import { useAuth, useSocket } from '@/stores/index'
import APIShopkeeper from '@/api/shopkeeper/index'
import { areTimesWithinNMinutes, getCurrentDateTime } from '@/utils/index'
const MessageContentDom = shallowRef<any>()
const dialogVisible = shallowRef(false)
const $props = defineProps<Props>()
const $emit = defineEmits<Emits>()
const { info } = storeToRefs(useAuth())
const { socket } = storeToRefs(useSocket())
const messageList = ref<any>([])

watch($props, (newValue) => {
    dialogVisible.value = newValue.modelValue
    if (!newValue.modelValue) {
        socket?.value?.removeEventListener('message', onMessage)
        messageList.value = []
    }
}, { immediate: true })

const queryParams = ref<any>({
    page: 1,
    limit: 10
})

watch(dialogVisible, (newValue) => {
    $emit('update:modelValue', newValue)
})

function onBeforeClose() {
    queryParams.value.page = 1
    messageList.value = []
    first.value = false
    dialogVisible.value = false
}

const message = shallowRef<string>('')

function handleSendMessage() {
    if (message.value) {
        sendMessage(message.value)
        message.value = ''
    }
}

function topPost() {
    nextTick(() => {
        const dom = (MessageContentDom.value as HTMLDivElement)
        dom.scrollTop = dom.scrollHeight
    })
}


const loading = shallowRef<boolean>(false)


const isPullGetMessageList = computed(() => {
    return !(queryParams.value.page * queryParams.value.limit >= total.value)
})

/** 获取双方的聊天记录 */
function getChatMessageLog() {
    first.value = true
    const mine = {
        id: (info.value.id as number)
    }
    const to = {
        id: ($props.shopInfo?.user_id as number)
    }
    loading.value = true
    APIShopkeeper.sendWsMessage({
        type: 'chatMessageList',
        ...queryParams.value,
        mine,
        to
    })
}

/** 指定用户发送信息 */
function sendMessage(content: string) {
    const mine = {
        id: (info.value.id as number),
        avatar: '',
        username: (info.value.username as string),
        content
    }

    const to = {
        id: ($props.shopInfo?.user_id as number)
    }

    APIShopkeeper.sendWsMessage({
        type: 'chatMessage',
        mine,
        to
    }).then(() => {
        const item: any = {
            create_time: getCurrentDateTime(),
            from_user_id: mine.id,
            content: mine.content
        }
        if (messageList.value.length == 0) {
            messageList.value.push({
                time: item.create_time,
                children: [item]
            })
        } else {
            const oneItem = messageList.value[messageList.value.length - 1].children?.at(-1)
            if (areTimesWithinNMinutes(oneItem.create_time, item.create_time, 5)) {
                messageList.value[messageList.value.length - 1].children.push(item)
            } else {
                messageList.value.push({
                    time: item.create_time,
                    children: [item]
                })
            }
        }
        topPost()

    })
}

const total = shallowRef<number>(0)

function onMessage(e: any) {
    const data = JSON.parse(e.data)
    const type = data.type
    switch (type) {
        /** 私聊 */
        case 'chatMessage':
            /** 将消息渲染到页面 */
            const item: any = {
                create_time: getCurrentDateTime(),
                from_user_id: data.fromid,
                content: data.content
            }
            if (messageList.value.length == 0) {
                messageList.value.push({
                    time: item.create_time,
                    children: [item]
                })
            } else {
                const oneItem = messageList.value[messageList.value.length - 1].children?.at(-1)
                if (areTimesWithinNMinutes(oneItem.create_time, item.create_time, 5)) {
                    messageList.value[messageList.value.length - 1].children.push(item)
                } else {
                    messageList.value.push({
                        time: item.create_time,
                        children: [item]
                    })
                }
            }
            topPost()
            break
        /** 聊天信息 */
        case 'chatMessageList':
            /** 将消息渲染到页面 */
            const messageData = data.result.data
            total.value = data.result.total
            messageData.reverse()
            const list: any[] = []
            messageData.forEach((item: any, index: number) => {
                if (index == 0) {
                    list.push({
                        time: item.create_time,
                        children: [item]
                    })
                } else {
                    const oneItem = list[list.length - 1].children?.at(-1)
                    if (areTimesWithinNMinutes(oneItem.create_time, item.create_time, 5)) {
                        list[list.length - 1].children.push(item)
                    } else {
                        list.push({
                            time: item.create_time,
                            children: [item]
                        })
                    }
                }
            })
            messageList.value = [...list, ...messageList.value]

            if (queryParams.value.page == 1) {
                topPost()
            } else {
                MessageContentDom.value.scrollTop = 731
            }
            loading.value = false
            break
    }
}

const first = shallowRef<boolean>(false)

function onOpen() {
    socket?.value?.addEventListener('message', onMessage)
    getChatMessageLog()
    MessageContentDom.value.addEventListener('scroll', (e: Event) => {
        if ((e.target as HTMLDivElement)?.scrollTop <= 0 && isPullGetMessageList.value && first.value) {
            queryParams.value.page += 1
            getChatMessageLog()
        }
    })
}

</script>

<template>
    <el-dialog class="dialog-message" v-model="dialogVisible" width="800" destroy-on-close :before-close="onBeforeClose"
        @open="onOpen" :show-close="false">
        <DialogClose :title="shopInfo?.user?.username" @close="onBeforeClose" />
        <div class="message-box" v-loading="loading">
            <div class="message-content" ref="MessageContentDom">
                <div v-for="(item, index) in messageList" :key="index">
                    <div class="time">{{ item.time }}</div>
                    <div v-for="itemChildren in item.children" :key="itemChildren.id">
                        <div class="side" v-if="itemChildren.from_user_id == shopInfo?.user_id">
                            <div class="avatar">
                                <img v-if="shopInfo?.user?.head_img" :src="shopInfo?.user?.head_img" alt="头像">
                            </div>
                            <div class="text">{{ itemChildren.content }}</div>
                        </div>
                        <div class="self" v-if="itemChildren.from_user_id == info.id">
                            <div class="text">{{ itemChildren.content }}</div>
                            <div class="avatar">
                                <img v-if="info.head_img" :src="info.head_img" alt="头像">
                            </div>
                        </div>
                    </div>

                </div>
            </div>
            <input v-model="message" class="send-message" type="text" placeholder="发送信息…（按回车键发送）"
                @keydown.enter="handleSendMessage">
        </div>
    </el-dialog>
</template>

<style lang="scss">
.dialog-message {
    padding: 0 !important;
    border-radius: 10px;

    .el-dialog__body {
        padding: 0 !important;
    }
}
</style>

<style lang="scss" scoped>
.dialog-message {
    .message-box {
        padding: 0 38px;
        padding-bottom: 30px;

        .message-content {
            height: 350px;
            overflow-y: auto;
            margin-bottom: 10px;
            padding: 0 10px;

            .side,
            .self {
                display: flex;
                align-items: center;
                gap: 0 8px;
                margin: 10px 0;

                .avatar {
                    width: 60px;
                    height: 60px;
                    background-color: #eeeeee;
                    border-radius: 50%;

                    img {
                        width: 100%;
                        height: 100%;
                        border-radius: 50%;
                    }
                }

                .text {
                    max-width: 414px;
                    background-color: rgba(247, 247, 247, 1);
                    padding: 10px 6px;
                }
            }

            .self {
                justify-content: flex-end;
            }


            .time {
                color: rgba(148, 148, 148, 1);
                font-size: 14px;
                text-align: center;
            }
        }

        .send-message {
            width: 100%;
            height: 50px;
            line-height: 20px;
            border-radius: 5px;
            background-color: rgba(255, 255, 255, 1);
            color: rgba(16, 16, 16, 1);
            font-size: 16px;
            border: 1px solid rgba(187, 187, 187, 1);
            outline: none;
            text-indent: 20px;
        }
    }
}
</style>
